package com.treasure.web.controller;

import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.treasure.common.model.SessionUser;
import com.treasure.common.model.SessionUserHolder;
import com.treasure.common.reponse.Response;
import com.treasure.common.types.Corp;
import com.treasure.domain.iqap.IntelligentAnswerProcessor;
import com.treasure.infrastructure.client.SseEmitterServer;
import com.treasure.web.command.request.chat.ChatHistoryDetailRequest;
import com.treasure.domain.domain.entity.QuestionRequest;
import com.treasure.web.command.request.chat.ChatHistoryRequest;
import com.treasure.web.command.request.chat.ChatRelationRequest;
import com.treasure.web.command.request.chat.ChatRequest;
import com.treasure.web.command.response.chat.ChatHistoryDetailResponse;
import com.treasure.web.command.response.chat.ChatHistoryResponse;
import com.treasure.common.model.ChatResponse;
import com.treasure.web.command.response.chat.ChatRelationResponse;
import com.treasure.web.service.IChatHistoryService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.List;

import static com.treasure.infrastructure.domain.llm.qianwen.client.QwenGenerationClient.SSE_END_KEY;

/**
 * 聊天交互历史（用户端）
 *
 * @author sunhongmin
 * @date 2023/9/1 10:39
 * @description
 */
@RestController
@RequiredArgsConstructor
@RequestMapping("/treasure")
@Slf4j
public class ConversationController {

    private final IChatHistoryService chatHistoryService;
    private final IntelligentAnswerProcessor intelligentAnswerProcessor;

    /**
     * 流式推送 conversation（SSE)
     */
    @PostMapping("/conversation")
    public SseEmitter conversation(@RequestBody ChatRequest chatRequest) throws UnsupportedEncodingException {
        QuestionRequest questionRequest = convertQuestionRequest(chatRequest);
        try {
            intelligentAnswerProcessor.conversationForChain(questionRequest, Boolean.FALSE);
            return SseEmitterServer.connect(chatRequest.getClientToken());
        } catch (Exception e) {
            return closeConnect(chatRequest, e);
        }
    }

    /**
     * 交互请求 （http）
     *
     * @param questionRequest
     */
    @PostMapping("/chat")
    @Deprecated
    public Response<ChatResponse> chat(@RequestBody QuestionRequest questionRequest) throws IOException, NoApiKeyException, InputRequiredException {
        return Response.success(intelligentAnswerProcessor.conversationForChain(questionRequest, Boolean.TRUE));
    }


    /**
     * 聊天记录
     *
     * @param chatRecordRequest 查询参数
     * @return 聊天历史
     */
    @PostMapping("/chat/history")
    public Response<ChatHistoryDetailResponse> chatDetailHistory(@RequestBody ChatHistoryDetailRequest chatRecordRequest) {
        SessionUser sessionUser = SessionUserHolder.getAndCheckSessionUser();
        return Response.success(chatHistoryService.getChatHistoryDetailList(new Corp(sessionUser.getCorpId()), chatRecordRequest));
    }

    /**
     * 会话记录
     *
     * @return 登录用户历史聊天摘要列表
     */
    @PostMapping("/chat/history/list")
    public Response<IPage<ChatHistoryResponse>> chatHistory(@RequestBody ChatHistoryRequest chatHistoryRequest) {
        SessionUser sessionUser = SessionUserHolder.getAndCheckSessionUser();
        return Response.success(chatHistoryService.getChatHistoryList(sessionUser, chatHistoryRequest));
    }

    /**
     * 知识库关联查询
     *
     * @param chatRelationRequest
     * @return
     */
    @PostMapping("/chat/question/relation")
    public Response<List<ChatRelationResponse>> chatRelation(@RequestBody ChatRelationRequest chatRelationRequest) {
        return Response.success(chatHistoryService.getQuestionRelationDocLit(chatRelationRequest));
    }

    @NotNull
    private static QuestionRequest convertQuestionRequest(ChatRequest chatRequest) throws UnsupportedEncodingException {
        QuestionRequest questionRequest = new QuestionRequest();
        questionRequest.setInteractionId(chatRequest.getInteractionId());
        questionRequest.setClientToken(chatRequest.getClientToken());
        questionRequest.setQuestion(URLDecoder.decode(chatRequest.getQuestion(), "UTF-8"));
        return questionRequest;
    }

    @NotNull
    private static SseEmitter closeConnect(ChatRequest chatRequest, Exception e) {
        log.error(">>> chatOfStream error:", e);
        SseEmitter connect = SseEmitterServer.connect(chatRequest.getClientToken());
        SseEmitterServer.sendMessage(chatRequest.getClientToken(), SSE_END_KEY);
        SseEmitterServer.removeUser(chatRequest.getClientToken());
        return connect;
    }
}
